/*
 * Copyright (c) 2006 Terracotta, Inc. All rights reserved.
 */
package org.terracotta.workmanager;

import commonj.work.Work;
import commonj.work.WorkEvent;
import commonj.work.WorkException;
import commonj.work.WorkItem;
import commonj.work.WorkListener;

/**
 * The work item, holds the work to be executed, status of the progress and the
 * future result.
 */
public class DefaultWorkItem implements WorkItem {

  protected volatile int status;

  protected final Work work;

  protected final WorkListener workListener;

  public DefaultWorkItem(final Work work, final WorkListener workListener) {
    this.work = work;
    this.status = WorkEvent.WORK_ACCEPTED;
    this.workListener = workListener;
  }

  public Work getResult() throws WorkException {
    if (status == WorkEvent.WORK_REJECTED) {
      throw new WorkException();
    }
    return work;
  }

  public synchronized void setStatus(final int status, final WorkException exception) {
    this.status = status;
    if (workListener != null) {
      switch (status) {
        case WorkEvent.WORK_ACCEPTED:
          workListener.workAccepted(new DefaultWorkEvent(WorkEvent.WORK_ACCEPTED, this, exception));
          break;
        case WorkEvent.WORK_REJECTED:
          workListener.workRejected(new DefaultWorkEvent(WorkEvent.WORK_REJECTED, this, exception));
          break;
        case WorkEvent.WORK_STARTED:
          workListener.workStarted(new DefaultWorkEvent(WorkEvent.WORK_STARTED, this, exception));
          break;
        case WorkEvent.WORK_COMPLETED:
          workListener.workCompleted(
              new DefaultWorkEvent(WorkEvent.WORK_COMPLETED, this, exception));
          break;
      }
    }
  }

  public synchronized int getStatus() {
    return this.status;
  }

  public WorkException newWorkException(final Throwable e) {
    e.printStackTrace();
    WorkException we = new WorkException(e.getMessage());
    setStatus(WorkEvent.WORK_REJECTED, we);
    Thread.currentThread().interrupt();
    return we;
  }

  @Override
  public String toString() {
    String status;
    switch (this.status) {
      case WorkEvent.WORK_ACCEPTED:
        status = "WORK_ACCEPTED";
        break;
      case WorkEvent.WORK_COMPLETED:
        status = "WORK_COMPLETED";
        break;
      case WorkEvent.WORK_REJECTED:
        status = "WORK_REJECTED";
        break;
      case WorkEvent.WORK_STARTED:
        status = "WORK_STARTED";
        break;
      case WorkEvent.WORK_NOOS:
        status = "WORK_NOOS";
        break;
      default:
        throw new IllegalStateException("illegal (unknown) status " + this.status);
    }
    return work.toString() + ":" + status;
  }
}
